package com.zxb.base.generator.web;

import java.io.File;
import java.util.List;
import com.zxb.base.generator.config.EngineConfig;
import com.zxb.base.generator.enm.FunctionEnum;
import com.zxb.base.generator.service.DdlService;
import com.zxb.base.generator.service.EngineService;
import com.zxb.base.generator.vo.ColumnVo;
import com.zxb.core.common.A;
import com.zxb.core.common.R;
import com.zxb.core.dao.auth.AuthMenu;
import com.zxb.core.dao.auth.AuthMenuDao;
import com.zxb.core.dao.generator.GenColumn;
import com.zxb.core.dao.generator.GenColumnDao;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Zxb
 */
@RestController
@AllArgsConstructor
@Api(tags = {"代码生成器"})
public class GeneratorController {

    private GenColumnDao columnDao;
    private AuthMenuDao menuDao;
    private EngineService engineService;
    private DdlService ddlService;

    @ApiOperation("查询数据库表")
    @GetMapping("/engine/table/list")
    public R<?> table(String schema, String prefix) {
        List<String> list = ddlService.findTableWithPrefix(schema, prefix);
        return R.success(list);
    }

    @ApiOperation("添加库表")
    @PostMapping("/engine/table/add")
    public R<?> addTable(String schema, String tableName, List<ColumnVo> columnVoList)  {
        return ddlService.addTable(schema, tableName, columnVoList);
    }

    @ApiOperation("删除库表")
    @PostMapping("/engine/table/del")
    public R<?> delTable(String schema, String tableName) {
        return ddlService.delTable(schema, tableName);
    }

    @ApiOperation("查询库表字段")
    @GetMapping("/engine/column/list")
    public R<?> column(String schema, String tableName) {
        List<ColumnVo> list = ddlService.findColumnByTable(tableName, schema);
        return R.success(list);
    }

    @ApiOperation("删除库表字段")
    @PostMapping("/engine/column/del")
    public R<?> delColumn(String schema, String tableName, String columnName) {
        return ddlService.dropColumn(schema, tableName, columnName);
    }

    @ApiOperation("批量更新或新增库表字段")
    @PostMapping("/engine/column/merge")
    public R<?> mergeColumn(String schema, String tableName, List<ColumnVo> columnVoList) {
        return ddlService.mergeColumnsForTable(schema, tableName, columnVoList);
    }

    @ApiOperation("重置库表的公共字段")
    @PostMapping("/engine/column/public/reset")
    public R<?> resetPubColumn(String schema, String tableName) {
        ddlService.dropPubColumn(schema, tableName);
        ddlService.addPubColumn(schema, tableName);
        return R.success();
    }

    @ApiOperation("为所有库表追加没有的公共字段")
    @PostMapping("/engine/column/public/repair")
    public R<?> repairPubColumn(String schema) {
        List<String> tableList = ddlService.findTable(schema);
        for (String table : tableList) {
            ddlService.addPubColumn(schema, table);
        }
        return R.success();
    }

    @ApiOperation("设置字段可见性")
    @PostMapping("/engine/col/visible/set")
    public R<?> setColVisible(String tableName, String columnName, Boolean isShow, String viewType) {
        GenColumn column = engineService.findGenColumnByTable(tableName, columnName);
        A.isInDatabase(column,"字段");
        if (FunctionEnum.LIST.name().equals(viewType)) {
            column.setListShow(isShow);
        } else if (FunctionEnum.EDIT.name().equals(viewType)) {
            column.setEditShow(isShow);
        } else if (FunctionEnum.INFO.name().equals(viewType)) {
            column.setInfoShow(isShow);
        } else if (FunctionEnum.BATCH.name().equals(viewType)) {
            column.setBatchShow(isShow);
        }
        columnDao.updateById(column);
        return R.success();
    }

    @ApiOperation("设置字段的表单类型")
    @PostMapping("/engine/col/type/set")
    public R<?> setColType(String tableName, String columnName, String compType) {
        GenColumn column = engineService.findGenColumnByTable(tableName, columnName);
        A.isInDatabase(column,"字段");
        column.setCompType(compType);
        columnDao.updateById(column);
        return R.success();
    }

    @ApiOperation("设置字段的参照表")
    @PostMapping("/engine/col/refer/set")
    public R<?> setColRefer(String tableName, String columnName, String referTableName, String referColumnName) {
        GenColumn column = engineService.findGenColumnByTable(tableName, columnName);
        A.isInDatabase(column,"字段");
        column.setReferTableName(referTableName);
        column.setReferColumnName(referColumnName);
        columnDao.updateById(column);
        return R.success();
    }

    @ApiOperation("初始化表的代码生成配置")
    @PostMapping("/engine/col/init")
    public R<?> initCol(String schema, String tableName) {
        List<ColumnVo> columnList = ddlService.findColumnByTable(tableName, schema);
        List<GenColumn> list = engineService.initTable(schema, tableName, columnList);
        return R.success(list);
    }


    @ApiOperation("生成实体")
    @PostMapping("/engine/entity/generate")
    public R<?> generateEntity(String schema, String tableName) {
        engineService.generateEntity(schema, tableName);
        return R.success();
    }

    @ApiOperation("生成列表增删改查代码")
    @PostMapping("/engine/crud/generate")
    public R<?> generateCrud(String schema, String tableName, String packageName, String vueLocation) {
        File f = new File(vueLocation);

        if (!f.exists()) {
            return R.error("未找到前端代码路径");
        }

        File vueFolder = new File(vueLocation + tableName.toLowerCase());
        if (!vueFolder.exists()) {
            vueFolder.mkdirs();
        }

        String location = vueFolder.getPath();
        EngineConfig.vueLocation.set(location);
        EngineConfig.packageName.set(packageName);

        engineService.generateEntity(schema, tableName);
        engineService.generateController(schema, tableName);
        engineService.generateService(schema, tableName);
        engineService.generateServiceImpl(schema, tableName);
        engineService.generateVue(schema, tableName);

        String lowerCaseTableName = tableName.toLowerCase();
        AuthMenu menu = new AuthMenu();
        menu.setPid(null);
        menu.setType(1);
        menu.setLayer(1);
        menu.setSort(1);
        menu.setName(lowerCaseTableName);
        menu.setCode(lowerCaseTableName.replace("_", ":"));
        menu.setLayout("/grid/" + lowerCaseTableName + "/Index.vue");
        menu.setIcon("laptop");
        menu.setUrl("/" + lowerCaseTableName.replace("_", "/"));
        menu.setIsUse(true);
        menuDao.save(menu);
        return R.success();
    }

    @ApiOperation("生成树操作代码")
    @PostMapping("/engine/tree/generate")
    public R<?> generateTree(String schema, String tableName) {
        engineService.generateTreeJava(tableName);
        engineService.generateTreeVue(schema, tableName);
        return R.success();
    }

    @ApiOperation("生成子表操作代码")
    @PostMapping("/engine/child/generate")
    public R<?> generateChild(String schema, String tableName, String parentTableName) {
        engineService.generateChildController(schema, tableName, parentTableName);
        engineService.generateChildVue(schema, tableName);
        return R.success();
    }
}
